package com.laviedesfons.mavenjhmtascplugin;

import com.anotherbigidea.flash.interfaces.SWFActions;
import com.anotherbigidea.flash.movie.Movie;
import com.anotherbigidea.flash.readers.MovieBuilder;
import com.anotherbigidea.flash.readers.SWFReader;
import com.anotherbigidea.flash.readers.TagParser;
import com.anotherbigidea.flash.writers.SWFTagDumper;
import com.anotherbigidea.util.Hex;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

/**
 * @goal package-swf
 * @author Romano
 */
public class PackageMojo extends ParentMojo {

    private MovieBuilder builder;

    private File[] getCompiledClasses(){
        // instead of .abclass, we could defines beans for mapping the bytecode content of a .abclass
        File sourceDirFile = new File(outputDir+"/classes");
        String[] okFileExtensions = {"abclass"};
        return sourceDirFile.listFiles(new CustomFileFilter(okFileExtensions));
    }

    private boolean isValidMainClass(){
        if( mainClass != null ) {
            int pointIndex = mainClass.indexOf(".");

            if (pointIndex != -1 &&
                    pointIndex != 0 &&
                        pointIndex != mainClass.length()-1){

                return mainClass.indexOf(".", pointIndex+1) == -1;
            }
        }
        return false;
    }

    private void createMainEntry(Movie movie)
            throws IOException{

        // splits className and methodName from mainClass String
        int pointIndex = mainClass.indexOf(".");
        String mainClassName = mainClass.substring(0, pointIndex);
        String mainMethodName = mainClass.substring(pointIndex+1,mainClass.length());

        // TODO METTRE EN DEBUG
        log("Main entry point : "+mainClassName+"."+mainMethodName);

        String[] lookupEntries ={
            "JHMTASC_MAIN",
            "this",
            mainClassName,
            mainMethodName
        };

        SWFActions acts =
                movie.getFrame(movie.getFrameCount()).actions(movie.getVersion());

        // juste reproducing MTASC_MAIN actionscript bytecode
        acts.start(0);
        acts.lookupTable( lookupEntries );
        acts.lookup( 0 );
        acts.storeInRegister(0);
        acts.pop();
        acts.lookup(1);
        acts.getVariable();
        acts.push(1);
        acts.lookup(2);
        acts.getVariable();
        acts.lookup(3);
        acts.callMethod();
        acts.pop();
        acts.end();
        acts.done();
    }

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        try {
            if(isValidMainClass()){

                builder = new MovieBuilder();
                TagParser tagParser = new TagParser(builder);

                FileInputStream in = null;
                SWFReader reader = null;

                // TODO resolve maven dependencies
                // TODO resolve intern depencies i.e exlude unused classes

                // retrieve all .abclass files
                File[] listFiles = getCompiledClasses();

                if(listFiles != null && listFiles.length > 0){
                    // build the final swf file by reading each .abclass
                    for(File abclassFile : listFiles){

                        System.out.println("");
                        System.out.println("TAG DUMP");
                        System.out.println("");

                        SWFTagDumper dumper = new SWFTagDumper(true, true);
                        TagParser dumpParser = new TagParser( dumper );
                        in = new FileInputStream(abclassFile);
                        reader = new SWFReader( dumpParser, in );
                        reader.readFile();
                        in.close();
                        //must flush - or the output will be lost when the process ends
                        dumper.flush();

                        System.out.println("HEX DUMP");
                        System.out.println("");

                        Hex.main(abclassFile);

                        System.out.println("");

                        debug("ActionScriptByteCodeClass: "+abclassFile.getName());
                        in = new FileInputStream(abclassFile);
                        reader = new SWFReader( tagParser, in );
                        reader.readFile();
                        in.close();
                    }

                    // adding main entry point
                    Movie movie = builder.getMovie();
                    createMainEntry(movie);

                    // setting header values
                    movie.setWidth(getHeaderWidth());
                    movie.setHeight(getHeaderHeight());
                    movie.setFrameRate(getHeaderFrameRate());

                    // force version to 8
                    movie.setVersion(8);

                    // write final swf file
                    movie.write(outputDir+"/"+finalName+".swf");
                } else {
                    throw new MojoFailureException("No .abclass found");
                }
            } else {
                throw new MojoFailureException("No mainClass provided, please provide a mainClass property as <mainClass>Class.method</mainClass>");
            }
        } catch (IOException ex) {
            getLog().info(ex);
        }
    }
}